
package com.xdf.wxbebarrel.service;

import com.xdf.wxbebarrel.dao.flux.UserMillMapper;
import com.xdf.wxbebarrel.model.Mill;
import com.xdf.wxbebarrel.model.UserMill;
import com.xdf.wxbebarrel.model.templateMessage.WebAuthorityUserInfo;
import com.xdf.wxbebarrel.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.xdf.wxbebarrel.dao.flux.UserMapper;
import com.xdf.wxbebarrel.model.User;
import tk.mybatis.mapper.util.Assert;

/**
 * @Description : 服务层实现类，由代码生成器自动生成
 * @Author : chanchaw
 * @Date : 2022-10-22 13:59:39
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper dao;
    @Autowired
    private UserMillMapper userMillMapper;
    @Autowired
    private WechatUtils wechatUtils;
    @Autowired
    private MillService millService;

    @Override
    public int insert(User record) {
        check4Insert(record);
        return dao.insert(record);
    }

    @Override
    public int insertSelective(User record) {
        check4Insert(record);
        return dao.insertSelective(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiInsert(List<User> list) {
        return dao.multiInsert(list);
    }

    @Override
    public int updateByPrimaryKey(User record) {
        return dao.updateByPrimaryKey(record);
    }

    @Override
    public int updateByPrimaryKeySelective(User record) {
        return dao.updateByPrimaryKeySelective(record);
    }

    @Transactional
    @Override
    public int deleteByPrimaryKey(Integer iid) {
        // 同时要删除 user_mill 中的数据
        User user = dao.selectByPrimaryKey(iid);
        userMillMapper.deleteByOpenid(user.getOpenId());
        return dao.deleteByPrimaryKey(iid);
    }

    @Override
    public User selectByPrimaryKey(Integer iid) {
        return dao.selectByPrimaryKey(iid);
    }

    @Override
    public List<User> selectAll(){
        return dao.selectAll();
    }

    @Override
    public int save(User record){
        check4Insert(record);
        return dao.save(record);
    }

    // 没有使用 xml 中的 multiSave 方法是因为无法批量回写自增主键
    @Transactional
    @Override
    public int multiSave(List<User> list){
        if(list == null || list.size()==0) return 0;
        list.forEach(item -> dao.save(item));
        return list.size();
    }

    /**=========================下面开始是固定模式代码=======================================*/
    public User selectBySid(String sid){
        return dao.selectBySid(sid);
    }

    // 返回true表示存在，false表示不存在
    public Boolean exists(String sid){
        User record = selectBySid(sid);
        return record == null ? false : true;
    }


    // 新增前检测，不可新增则抛出异常
    private void check4Insert(User record){
        if(record == null) throw new BusinessException("新增的对象不可为空！");
//        String sid = record.getSid();
//        if(sid == null) throw new BusinessException("编号不可为空！");
//        if(exists(sid)) throw new BusinessException("编号" + sid + "已经存在，请更换后再次保存！");
    }
    //=================以上是自动生成的代码，自定义代码请写在下面==================

    @Transactional
    @Override
    public int updateRealName(String openId,String realName,String mill){
        User user = dao.selectBySid(openId);
        if(user == null) throw new BusinessException("没有找到openId=" + openId + "的用户！");
        user.setOpenId(openId);
        user.setRealName(realName);

        // 修改 user_mill 中的相关数据
        UserMill um = new UserMill();
        um.setOpenId(openId);
        um.setMillSid(mill);
        userMillMapper.save(um);

        return dao.updateByPrimaryKeySelective(user);
    }

    // 查询获取所有管理员
    public List<User> selectAuditors(){
        List<User> userList = dao.selectAll();
        if(userList == null || userList.size() == 0) return null;
        return userList.stream().filter(item -> item.getAudit()).collect(Collectors.toList());
    }

    @Override
    public Boolean effectiveUser(String openId) {
        UserMill userMill = userMillMapper.selectMill(openId);
        return userMill == null ? false : true;
    }

    @Override
    public User selectByOpenId(String openId) {
        return dao.selectByOpenId(openId);
    }

    @Override
    public int deleteByOpenid(String openId) {
        return dao.deleteByOpenid(openId);
    }

    @Override
    public int registerNewUser(String code,Integer millIid,String realName) throws Exception {
        // 根据 html 页面 code 获取微信用户信息
        WebAuthorityUserInfo webAuthorityUserInfo = WechatWebAuthorityUtils.getWebAuthorityUserInfo(code);
        if(webAuthorityUserInfo == null) throw new BusinessException("使用code获取用户信息失败，请重新进入页面！");
        String openId = webAuthorityUserInfo.getOpenid();
//        User user = dao.selectByOpenId(openId);
//        if(user != null) throw new BusinessException("您已经注册过，无需重复注册！");
        String nickName = webAuthorityUserInfo.getNickname();
//        Mill mill = millService.selectByPrimaryKey(millIid);
//        if(mill == null) throw new BusinessException("没有主键是"+ millIid +"的客户！");

        // 推送给管理员模板消息，点击详情后进入审核通过的页面
        wechatUtils.pushMsgAudit(openId,nickName,realName,millIid);
        return 1;
    }

    @Override
    public int registerNewUser(String openId, String nickName, String realName, String millName,String code,String role) {
        if(hasRelationShip(openId, millName)) throw new BusinessException("用户【" + realName + "】已关联到【" + millName + "】无需重复关联！");
        User user1 = dao.selectByOpenId(openId);
        // 新用户注册
        if(user1 == null){
            User user = new User();
            user.setOpenId(openId);
            user.setNickName(nickName);
            user.setRealName(realName);
            dao.insertSelective(user);
        }

        UserMill userMill = new UserMill();
        userMill.setOpenId(openId);
        userMill.setMillSid(millName);
        userMill.setRole(role);
        userMillMapper.insertSelective(userMill);

        // 向用户推送注册成功的模板消息 - 必须是8个元素
        String[] msg = {"注册成功",realName, DatetimeUtils.formatNow(),"正常","已成功注册！","","",""};
        wechatUtils.pushMsg(openId,msg,null);// 推送给新用户
        List<User> users = dao.selectAllAuditors();

        // 根据 code 获取审核用户的管理员微信
        String openIdAdmin = "";
        try {
            openIdAdmin = wechatUtils.getOpenidByOAuth(code);
        } catch (IOException e) {
            throw new BusinessException(e.getMessage());
        }

        // 没有获取当前执行审核的管理员微信 openId 时推送消息告知 me
        List<User> mes = dao.selectMe();
        if(openIdAdmin.length() == 0){
            if(mes.size() > 0){
                String[] msg1 = {"审核新用户时没有获取到管理员微信openId",realName, DatetimeUtils.formatNow(),"正常","用户注册成功，但是没有获取审核的管理员openId","","",""};
                mes.forEach(item -> wechatUtils.pushMsg(item.getOpenId(),msg1,null));
            }
            return 1;
        }

        User user2 = dao.selectByOpenId(openIdAdmin);
        String[] msg2Admin = {"管理员【" + user2.getRealName() + "】已审核下面用户的注册申请",realName, DatetimeUtils.formatNow(),"正常","已成功注册！","","",""};
        if(users.size()>0){
            users.forEach(item -> wechatUtils.pushMsg(item.getOpenId(),msg2Admin,null));
        }
        return 1;
    }

    @Override
    public List<User> selectAllAuditors() {
        return dao.selectAllAuditors();
    }

    private Boolean hasRelationShip(String openId,String millName){
        UserMill userMill = userMillMapper.selectUserMill(openId, millName);
        return userMill == null ? false : true;
    }

    @Override
    public int setClientRelationship(Integer userIid,Integer millIid,String role){
        return dao.setClientRelationship(userIid,millIid,role);
    }

    @Override
    public int setClientRelationshipMult(List<Integer> userIidList,List<Integer> millIidList,String role){
        Assert.notEmpty(userIidList,"用户不可为空!");
        Assert.notEmpty(millIidList,"客户不可为空!");
        Assert.notEmpty(role,"角色不可为空!");

        userIidList.forEach(userIid -> millIidList.forEach(millIid -> setClientRelationship(userIid,millIid,role)));
        return 1;
    }
}